home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Tool Chest / Dev.CD Feb 97 TC.toast / Sample Code / Development Tools & Languages / AppsToGo / DTS.Lib / AERequired.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  11.2 KB  |  404 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:        DTS.Lib
  5. ** File:        AERequired.c
  6. ** Written by:  Eric Soldan
  7. **
  8. ** Copyright © 1990-1991 Apple Computer, Inc.
  9. ** All rights reserved.
  10. **
  11. ** This code implements the required AppleEvents, specific to DTS.Lib.
  12. */
  13.  
  14. /* You may incorporate this sample code into your applications without
  15. ** restriction, though the sample code has been provided "AS IS" and the
  16. ** responsibility for its operation is 100% yours.  However, what you are
  17. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  18. ** after having made changes. If you're going to re-distribute the source,
  19. ** we require that you make it clear in the source that the code was
  20. ** descended from Apple Sample Code, but that you've made changes. */
  21.  
  22.  
  23.  
  24. /*****************************************************************************/
  25.  
  26.  
  27.  
  28. #include "DTS.Lib2.h"
  29. #include "DTS.Lib.protos.h"
  30.  
  31. #ifndef __GESTALTEQU__
  32. #include <GestaltEqu.h>
  33. #endif
  34.  
  35.  
  36.  
  37. /*****************************************************************************/
  38.  
  39.  
  40.  
  41. #define kTimeOutInTicks (60 * 30)    /* 30 second timeout. */
  42.  
  43. static pascal OSErr    DoAEOpenDocuments(AppleEvent *message, AppleEvent *reply, long refcon);
  44. static pascal OSErr    DoAEPrintDocuments(AppleEvent *message, AppleEvent *reply, long refcon);
  45. static pascal OSErr    DoAEQuitApplication(AppleEvent *message, AppleEvent *reply, long refcon);
  46. static OSErr        OpenDocEventHandler(AppleEvent *message, AppleEvent *reply, short mode);
  47.  
  48.  
  49.  
  50. /*****************************************************************************/
  51.  
  52.  
  53.  
  54. AEHandler gRequiredAppleEventHandlers[] = {
  55.     { kCoreEventClass,        kAEOpenApplication,        (AEEventHandlerProcPtr)DoAEOpenApplication,        nil },
  56.     { kCoreEventClass,        kAEOpenDocuments,        (AEEventHandlerProcPtr)DoAEOpenDocuments,        nil },
  57.     { kCoreEventClass,        kAEPrintDocuments,        (AEEventHandlerProcPtr)DoAEPrintDocuments,        nil },
  58.     { kCoreEventClass,        kAEQuitApplication,        (AEEventHandlerProcPtr)DoAEQuitApplication,        nil }
  59.         /* The above are the four required AppleEvents. */
  60. };
  61.  
  62. #define kNumKeywords (sizeof(gRequiredAppleEventHandlers) / sizeof(AEHandler))
  63.  
  64. Boolean        gHasAppleEvents = false;
  65. Boolean        gHasPPCToolbox  = false;
  66. DescType    gAERequiredType;
  67.  
  68. extern TreeObjHndl    gWindowFormats;
  69. extern Boolean        gNoFinderPrint;
  70.  
  71.  
  72.  
  73. /*****************************************************************************/
  74.  
  75.  
  76.  
  77. extern Boolean        gQuitApplication, gNoDefaultDocument, gInBackground;
  78. extern short        gPrintPage;
  79.  
  80. extern Cursor        *gCursorPtr;
  81. extern OSType        gAppWindowType;
  82.  
  83.  
  84.  
  85. /*****************************************************************************/
  86. /*****************************************************************************/
  87.  
  88. #ifdef applec
  89. #pragma segment ATGAppleEvents
  90. #endif
  91.  
  92. /*****************************************************************************/
  93. /*****************************************************************************/
  94.  
  95.  
  96.  
  97. /* Intializes AppleEvent dispatcher table for the required events.  It also
  98. ** determines if the machine is PPCBrowser and AppleEvent capable.  If so,
  99. ** the booleans gHasAppleEvents and gHasPPCToolbox are set true.  This function
  100. ** must be the first AppleEvents initialization DTS.framework function called, as the
  101. ** other functions depend on the booleans being set correctly. */
  102.  
  103. OSErr    InitRequiredAppleEvents(void)
  104. {
  105.     OSErr    err;
  106.     long    result;
  107.     short    i;
  108.  
  109.     gHasPPCToolbox  = (Gestalt(gestaltPPCToolboxAttr, &result) ? false : result != 0);
  110.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &result) ? false : result != 0);
  111.  
  112.     if (gHasAppleEvents) {
  113.  
  114.         for (i = 0; i < kNumKeywords; ++i) {
  115.  
  116.             if (!gRequiredAppleEventHandlers[i].theUPP)
  117.                 gRequiredAppleEventHandlers[i].theUPP =
  118.                     NewAEEventHandlerProc(gRequiredAppleEventHandlers[i].theHandler);
  119.  
  120.             err = AEInstallEventHandler(
  121.                 gRequiredAppleEventHandlers[i].theEventClass,    /* What class to install.  */
  122.                 gRequiredAppleEventHandlers[i].theEventID,        /* Keywords to install.    */
  123.                 gRequiredAppleEventHandlers[i].theUPP,            /* The AppleEvent handler. */
  124.                 0L,                                                /* Unused refcon.           */
  125.                 false                                            /* Only for our app.       */
  126.             );
  127.             if (err) {
  128.                 HCenteredAlert(rErrorAlert, nil, gAlertFilterUPP);
  129.                 return(err);
  130.             }
  131.         }
  132.     }
  133.  
  134.     return(noErr);
  135. }
  136.  
  137.  
  138.  
  139. /*****************************************************************************/
  140.  
  141.  
  142.  
  143. /* This function opens a new DTS.framework document due to an AppleEvents request. */
  144.  
  145. pascal OSErr    DoAEOpenApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  146. {
  147. #ifndef __MWERKS__
  148. #pragma unused (message, reply, refcon)
  149. #endif
  150.  
  151.     FileRecHndl    frHndl;
  152.     OSErr        err;
  153.     short        i;
  154.     TreeObjHndl    wobj;
  155.     long        attr;
  156.  
  157.     gAERequiredType = 'oapp';
  158.  
  159.     gCursorPtr = nil;
  160.         /* Force re-calc of cursor region and cursor to use. */
  161.  
  162.     err = noErr;
  163.     if (gWindowFormats) {
  164.         for (i = (*gWindowFormats)->numChildren; i;) {
  165.             wobj = GetChildHndl(gWindowFormats, --i);
  166.             attr = mDerefWFMT(wobj)->attributes;
  167.             if (!(attr & kwRuntimeOnlyDoc)) {
  168.                 if (attr & kwAutoNew) {
  169.                     err = NewDocumentWindow(&frHndl, mDerefWFMT(wobj)->sfType, true);
  170.                     if (err) break;
  171.                 }
  172.             }
  173.         }
  174.     }
  175.     else {
  176.         if (!gNoDefaultDocument) {
  177.             err = NewDocument(&frHndl, gAppWindowType, true);
  178.             if (!err) {
  179.                 if (frHndl) {
  180.                     err = DoNewWindow(frHndl, nil, GetNextWindow(nil, 0), (WindowPtr)-1);
  181.                     if (err)
  182.                         DisposeDocument(frHndl);
  183.                 }
  184.             }
  185.         }
  186.     }
  187.  
  188.     gAERequiredType = 0;
  189.  
  190.     return(err);
  191. }
  192.  
  193.  
  194.  
  195. /*****************************************************************************/
  196.  
  197.  
  198.  
  199. /* This function opens existing DTS.framework documents due to an AppleEvents request. */
  200.  
  201. static pascal OSErr    DoAEOpenDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  202. {
  203. #ifndef __MWERKS__
  204. #pragma unused (refcon)
  205. #endif
  206.  
  207.     OSErr    err;
  208.  
  209.     gAERequiredType = 'odoc';
  210.  
  211.     gCursorPtr = nil;        /* Force re-calc of cursor region and cursor to use. */
  212.     err = OpenDocEventHandler(message, reply, 0);
  213.         /* The 0 means regular open document. */
  214.  
  215.     gAERequiredType = 0;
  216.  
  217.     return(err);
  218. }
  219.  
  220.  
  221.  
  222. /*****************************************************************************/
  223.  
  224.  
  225.  
  226. /* This function prints DTS.framework documents due to an AppleEvents request. */
  227.  
  228. static pascal OSErr    DoAEPrintDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  229. {
  230. #ifndef __MWERKS__
  231. #pragma unused (refcon)
  232. #endif
  233.  
  234.     short                openMode;
  235.     ProcessSerialNumber    cpsn, fpsn;
  236.     Boolean                procsSame;
  237.     OSErr                err;
  238.  
  239.     if (gNoFinderPrint) err = DoAEOpenDocuments(message, reply, refcon);
  240.     else {
  241.         gAERequiredType = 'pdoc';
  242.         gCursorPtr = nil;                /* Force re-calc of cursor region and cursor to use. */
  243.  
  244.         openMode = 1;
  245.         if (!AEInteractWithUser(kTimeOutInTicks, nil, nil))
  246.             ++openMode;
  247.  
  248.         GetCurrentProcess(&cpsn);        /* We may have been moved to the front. */
  249.         GetFrontProcess(&fpsn);
  250.         SameProcess(&cpsn, &fpsn, &procsSame);
  251.         gInBackground = !procsSame;
  252.  
  253.         err = OpenDocEventHandler(message, reply, openMode);
  254.             /* openMode is either 1 or 2, depending if user interaction is okay. */
  255.  
  256.         gAERequiredType = 0;
  257.     }
  258.  
  259.     return(err);
  260. }
  261.  
  262.  
  263.  
  264. /*****************************************************************************/
  265.  
  266.  
  267.  
  268. /* This function sets a quit flag so that DTS.framework will quit due to an
  269. ** AppleEvents request. */
  270.  
  271. static pascal OSErr    DoAEQuitApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  272. {
  273. #ifndef __MWERKS__
  274. #pragma unused (message, reply, refcon)
  275. #endif
  276.  
  277.     OSErr    err;
  278.  
  279.     gCursorPtr = nil;
  280.         /* Force re-calc of cursor region and cursor to use. */
  281.  
  282.     if (DisposeAllWindows()) {
  283.         gQuitApplication = true;
  284.         err = noErr;
  285.     }
  286.     else err = errAEEventNotHandled;
  287.         /* All windows didn't close because user cancelled the quit. */
  288.  
  289.     return(err);
  290. }
  291.  
  292.  
  293.  
  294. /*****************************************************************************/
  295.  
  296.  
  297.  
  298. /* Called when we recieve an AppleEvent with an ID of "kAEOpenDocuments".
  299. ** This routine gets the direct parameter, parses it up into little FSSpecs,
  300. ** and opens each indicated file.  It also shows the technique to be used in
  301. ** determining if you are doing everything the AppleEvent record is telling
  302. ** you.  Parameters can be divided up into two groups: required and optional.
  303. ** Before executing an event, you must make sure that you've read all the
  304. ** required events.  This is done by making an "any more?" call to the
  305. ** AppleEvent manager. */
  306.  
  307. static OSErr    OpenDocEventHandler(AppleEvent *message, AppleEvent *reply, short mode)
  308. {
  309. #ifndef __MWERKS__
  310. #pragma unused (reply)
  311. #endif
  312.  
  313.     OSErr        err;
  314.     OSErr        err2;
  315.     AEDesc        theDesc;
  316.     FSSpec        theFSS;
  317.     short        loop;
  318.     long        numFilesToOpen, wkind;
  319.     AEKeyword    ignoredKeyWord;
  320.     DescType    ignoredType;
  321.     Size        ignoredSize;
  322.     FileRecHndl    frHndl;
  323.     WindowPtr    docWindow, fwindow;
  324.  
  325.     theDesc.dataHandle = nil;
  326.         /* Make sure disposing of the descriptors is okay in all cases.
  327.         ** This will not be necessary after 7.0b3, since the calls that
  328.         ** attempt to create the descriptors will nil automatically
  329.         ** upon failure. */
  330.  
  331.     err = AEGetParamDesc(message, keyDirectObject, typeAEList, &theDesc);
  332.     if (err)
  333.         return(err);
  334.  
  335.     if (!MissedAnyParameters(message)) {
  336.  
  337. /* Got all the parameters we need.  Now, go through the direct object,
  338. ** see what type it is, and parse it up. */
  339.  
  340.         err = AECountItems(&theDesc, &numFilesToOpen);
  341.         if (!err) {
  342.             /* We have numFilesToOpen that need opening, as either a window
  343.             ** or to be printed.  Go to it... */
  344.  
  345.             for (loop = 1; ((loop <= numFilesToOpen) && (!err)); ++loop) {
  346.                 err = AEGetNthPtr(        /* GET NEXT IN THE LIST...         */
  347.                     &theDesc,            /* List of file names.             */
  348.                     loop,                /* Item # in the list.             */
  349.                     typeFSS,            /* Item is of type FSSpec.         */
  350.                     &ignoredKeyWord,    /* Returned keyword -- we know.  */
  351.                     &ignoredType,        /* Returned type -- we know.     */
  352.                     (Ptr)&theFSS,        /* Where to put the FSSpec info. */
  353.                     sizeof(theFSS),        /* Size of the FSSpec info.         */
  354.                     &ignoredSize        /* Actual size -- we know.         */
  355.                 );
  356.                 if (err) break;
  357.  
  358.                 err = OpenDocument(&frHndl, &theFSS, fsRdWrPerm);
  359.                 if (err) break;
  360.  
  361.                 docWindow = (*frHndl)->fileState.window;
  362.                 if (!docWindow) {        /* New file being opened. */
  363.                     gPrintPage = mode;
  364.                         /* Open the window off-screen if we are printing.
  365.                         ** We use the gPrintPage global to flag this.  Normally, the
  366.                         ** gPrintPage global is to tell ImageDocument if we are imaging
  367.                         ** to the window or to paper.  We don't need it for this yet,
  368.                         ** as we can't image the document until it is opened.  DoNewWindow()
  369.                         ** uses gPrintPage as a flag to open the window off-screen, but
  370.                         ** visible, so that PrintMonitor can use the title of the window
  371.                         ** as the document name that is being printed. */
  372.  
  373.                     err = DoNewWindow(frHndl, &docWindow, GetNextWindow(nil, 0), (WindowPtr)-1);
  374.                     if (err)
  375.                         DisposeDocument(frHndl);
  376.                     else {
  377.                         if (gPrintPage) {
  378.                             err  = PrintDocument(frHndl, (mode == 2), (loop == 1));
  379.                             mode = 1;    /* No interaction mode (mode == 2) only valid
  380.                                         ** for the first printed document. */
  381.                             DisposeDocument(frHndl);
  382.                             DisposeAnyWindow(docWindow);
  383.                         }
  384.                     }
  385.                     gPrintPage = 0;
  386.                         /* Put the ImageDocument controlling global back to normal. */
  387.                 }
  388.                 else {
  389.                     wkind   = (*frHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog);
  390.                     fwindow = FrontWindowOfType(wkind, true);
  391.                     CleanSendInFront(docWindow, fwindow);
  392.                 }
  393.             }
  394.         }
  395.     }
  396.     DonePrinting();        /* Clean up after printing, if we did any. */
  397.  
  398.     err2 = AEDisposeDesc(&theDesc);
  399.     return(err ? err : err2);
  400. }
  401.  
  402.  
  403.  
  404.